{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Randomness" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1 How can the LC-3 create random numbers?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It can't. It is a deterministic computer with no means of reaching outside of itself." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.2 Pseudo-Random Number Generator Algorithm" ] }, { "cell_type": "code", "execution_count": 146, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "70\n", "490\n", "3430\n", "24010\n", "4235\n", "29645\n", "10913\n", "10857\n", "10465\n", "7721\n", "21280\n", "17892\n", "26943\n", "24766\n", "9527\n", "1155\n", "8085\n", "23828\n", "2961\n", "20727\n" ] } ], "source": [ "%%python\n", "\n", "## Algorithm for the iteration x = a * x % m\n", "## Using Schrage's method\n", "\n", "a = 7 ## the multplicative contants\n", "m = (2 ** 15) - 1 ## modulus\n", "x = 10 ## random seed\n", "\n", "q = m // a\n", "r = m % a\n", "for i in range(20):\n", " x = a * (x % q) - r * (x // q)\n", " if x < 0:\n", " x = x + m\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The LC-3 Assembly code:\n", "\n", "* https://athena.brynmawr.edu/jupyter/hub/dblank/public//CS240%20Computer%20Organization/2015-Fall/Notes/Randomness%20in%20LC-3.ipynb\n", "\n", "Produces **exactly** the same numbers, in the same sequence." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Languages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What have ween seen so far:\n", "\n", "1. Machine code - zeros and ones\n", "2. Assembly Language\n", " * two-pass system: labels\n", " * mnemonics for instructions, registers, etc.\n", " * directives (.FILL, .STRINGZ, .STRINGC)\n", " * decimal, hex representations\n", "3. C Language\n", " * macros, defines, conditional compiling\n", " * functions\n", " * structs\n", " * memory functions\n", " * libraries\n", " * Some optimizations\n", "4. C++ Language\n", " * garbage collection\n", " * OOP - Object-Oriented Programming\n", " * inheritance\n", " * public/private\n", "5. Advanced Languages (Python, Java, Scheme, JavaScript, etc.)\n", " * Many have their own virtual machine and assembly language\n", " * Many have a Just-In-Time Compiler (JIT)\n", " * Adapt as they run (uses statistics of specifics)\n", " * Largely, Machine Learning/Artificial Intelligence has not been used yet\n", " * Advanced functionality: \n", " * Type Inference\n", " * Backtracking\n", " * Pure Functional" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3. The C Programming Language" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3.1 Overview" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Generally described as:\n", "\n", "* Statically Typed - types checked at compile type\n", "* Weakly Typed - programmer can manipulate types (convert one to another, casting)\n", "* \"Super assembly\"\n", "* Can write code that translates almost directly into assembly language instructions\n", "* \"Syntactic sugar\" - easy to write/read; fast\n", "* Generates necessary instructions for handling functions, and structs\n", "* There are C compilers for \"all\" hardware\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3.2 Hello, world!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```c\n", "#include \n", "\n", "int main() {\n", " printf(\"Hello, world!\");\n", " return 0;\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* All variables and functions must be defined before use\n", "* All variables and functions have a type\n", " * int, double, float\n", " * uint - unsigned int\n", " * char is really uint\n", " * strings are arrays of char\n", "* Arrays - contiguous blocks of memory\n", " * the type determines the offset between elements\n", " * they don't know how long they are" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 4. C with Linux" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Create a text file with C source code in it\n", " * must have a main()\n", " * type can be int, or void\n", " * include additional libraries with #include\n", "1. Compile it\n", "1. Run it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.1 Create a C source code file" ] }, { "cell_type": "code", "execution_count": 149, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created file '/home/dblank/public_html/CS240 Computer Organization/2015-Fall/Notes/Test1.c'.\n" ] } ], "source": [ "%%file Test1.c\n", "\n", "#include \n", "int main() {\n", " printf(\"Testing 1, 2, 3...\\n\");\n", " return 0;\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.2 Compile it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using the GNU C Compiler:" ] }, { "cell_type": "code", "execution_count": 150, "metadata": { "collapsed": true }, "outputs": [], "source": [ "! gcc -o Test1 Test1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.3 Execute it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The current directory (called \".\") isn't in your search PATH, so we have to give the path to it." ] }, { "cell_type": "code", "execution_count": 151, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Testing 1, 2, 3...\r\n", "\n" ] } ], "source": [ "! ./Test1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 5. C Details" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NOTES:\n", "\n", "* If you want to get input from the user using gcc, you'll need to run in a terminal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.1 Interface with Operating System" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* argc - count\n", "* argv - string parameters\n", "* return value (must be int, if one)\n", " * called \"exit codes\"; each OS has their own\n", " * Linux/bash:\n", " * OK 0 /* successful termination */\n", " * BASE 64 /* base value for error messages */\n", " * USAGE 64 /* command line usage error */\n", " * DATAERR 65 /* data format error */\n", " * ...\n", "* Can print to terminal\n", "\n", "```c\n", "#include \n", "\n", "int main(int argc, char **argv) {\n", " printf(\"Hello World\");\n", " return 0;\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.2 Variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```c\n", "// Old style:\n", "void main() {\n", " int x; // define and use variables\n", " float f;\n", " \n", " x = 1;\n", " f = 3.2;\n", "}\n", "\n", "// Newer style:\n", "void main() {\n", " int x = 1; // define and use variables\n", " float f = 3.2;\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.3 Pointers\n", "\n", "In C, you can have variables that work with memory addresses. These are called \"pointers\". They expose the underlying way the system creates ans uses variables.\n", "\n", "Arrays are nothing more than arrays with a type, so that you can figure out how far apart items are in memory.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```c\n", " int x = 7;\n", " int *px = &x;\n", "```" ] }, { "cell_type": "code", "execution_count": 268, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created file '/home/dblank/public_html/CS240 Computer Organization/2015-Fall/Notes/Pointers.c'.\n" ] } ], "source": [ "%%file Pointers.c\n", "\n", "#include \n", "\n", "int main(int argc, char **argv) {\n", " int x = 7;\n", " int *px = &x; \n", " printf(\"x is: %d\\n\", x);\n", " printf(\"px is: %d\\n\", *px);\n", "}\n" ] }, { "cell_type": "code", "execution_count": 269, "metadata": { "collapsed": false }, "outputs": [], "source": [ "!gcc -o Pointers Pointers.c" ] }, { "cell_type": "code", "execution_count": 270, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x is: 7\r\n", "px is: 7\r\n", "\n" ] } ], "source": [ "!./Pointers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.4 Arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```c\n", " int array[] = {1, 2, 3};\n", " char *string = \"This is a string\";\n", " char *sarray[] = {\"Hello\", \"world\"};\n", "```" ] }, { "cell_type": "code", "execution_count": 257, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created file '/home/dblank/public_html/CS240 Computer Organization/2015-Fall/Notes/Arrays.c'.\n" ] } ], "source": [ "%%file Arrays.c\n", "\n", "#include \n", "\n", "int main(int argc, char **argv) {\n", "\n", " char *string = \"This is a string\\n\";\n", " char *sarray1[] = {\"Hello\", \"world\"};\n", "\n", " printf(string);\n", " printf(sarray1[0]);\n", "}\n" ] }, { "cell_type": "code", "execution_count": 258, "metadata": { "collapsed": false }, "outputs": [], "source": [ "!gcc -o Arrays Arrays.c" ] }, { "cell_type": "code", "execution_count": 259, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a string\r\n", "Hello\n" ] } ], "source": [ "! ./Arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Disassembly of GCC\n", "\n" ] }, { "cell_type": "code", "execution_count": 273, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\r\n", "Test1: file format elf64-x86-64\r\n", "\r\n", "\r\n", "Disassembly of section .interp:\r\n", "\r\n", "0000000000400200 <.interp>:\r\n", " 400200:\t2f \t(bad) \r\n", " 400201:\t6c \tinsb (%dx),%es:(%rdi)\r\n", " 400202:\t69 62 36 34 2f 6c 64 \timul $0x646c2f34,0x36(%rdx),%esp\r\n", " 400209:\t2d 6c 69 6e 75 \tsub $0x756e696c,%eax\r\n", " 40020e:\t78 2d \tjs 40023d <_init-0x153>\r\n", " 400210:\t78 38 \tjs 40024a <_init-0x146>\r\n", " 400212:\t36 \tss\r\n", " 400213:\t2d 36 34 2e 73 \tsub $0x732e3436,%eax\r\n", " 400218:\t6f \toutsl %ds:(%rsi),(%dx)\r\n", " 400219:\t2e 32 00 \txor %cs:(%rax),%al\r\n", "\r\n", "Disassembly of section .note.ABI-tag:\r\n", "\r\n", "000000000040021c <.note.ABI-tag>:\r\n", " 40021c:\t04 00 \tadd $0x0,%al\r\n", " 40021e:\t00 00 \tadd %al,(%rax)\r\n", " 400220:\t10 00 \tadc %al,(%rax)\r\n", " 400222:\t00 00 \tadd %al,(%rax)\r\n", " 400224:\t01 00 \tadd %eax,(%rax)\r\n", " 400226:\t00 00 \tadd %al,(%rax)\r\n", " 400228:\t47 \trex.RXB\r\n", " 400229:\t4e 55 \trex.WRX push %rbp\r\n", " 40022b:\t00 00 \tadd %al,(%rax)\r\n", " 40022d:\t00 00 \tadd %al,(%rax)\r\n", " 40022f:\t00 02 \tadd %al,(%rdx)\r\n", " 400231:\t00 00 \tadd %al,(%rax)\r\n", " 400233:\t00 06 \tadd %al,(%rsi)\r\n", " 400235:\t00 00 \tadd %al,(%rax)\r\n", " 400237:\t00 12 \tadd %dl,(%rdx)\r\n", " 400239:\t00 00 \tadd %al,(%rax)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .note.gnu.build-id:\r\n", "\r\n", "000000000040023c <.note.gnu.build-id>:\r\n", " 40023c:\t04 00 \tadd $0x0,%al\r\n", " 40023e:\t00 00 \tadd %al,(%rax)\r\n", " 400240:\t14 00 \tadc $0x0,%al\r\n", " 400242:\t00 00 \tadd %al,(%rax)\r\n", " 400244:\t03 00 \tadd (%rax),%eax\r\n", " 400246:\t00 00 \tadd %al,(%rax)\r\n", " 400248:\t47 \trex.RXB\r\n", " 400249:\t4e 55 \trex.WRX push %rbp\r\n", " 40024b:\t00 be 88 16 16 c8 \tadd %bh,-0x37e9e978(%rsi)\r\n", " 400251:\tbd 84 f7 ca 9e \tmov $0x9ecaf784,%ebp\r\n", " 400256:\t5c \tpop %rsp\r\n", " 400257:\t77 1f \tja 400278 <_init-0x118>\r\n", " 400259:\tc0 3a 2f \tsarb $0x2f,(%rdx)\r\n", " 40025c:\ta3 \t.byte 0xa3\r\n", " 40025d:\tb6 ad \tmov $0xad,%dh\r\n", " 40025f:\t8c \t.byte 0x8c\r\n", "\r\n", "Disassembly of section .gnu.hash:\r\n", "\r\n", "0000000000400260 <.gnu.hash>:\r\n", " 400260:\t01 00 \tadd %eax,(%rax)\r\n", " 400262:\t00 00 \tadd %al,(%rax)\r\n", " 400264:\t01 00 \tadd %eax,(%rax)\r\n", " 400266:\t00 00 \tadd %al,(%rax)\r\n", " 400268:\t01 00 \tadd %eax,(%rax)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .dynsym:\r\n", "\r\n", "0000000000400280 <.dynsym>:\r\n", "\t...\r\n", " 400298:\t01 00 \tadd %eax,(%rax)\r\n", " 40029a:\t00 00 \tadd %al,(%rax)\r\n", " 40029c:\t20 00 \tand %al,(%rax)\r\n", "\t...\r\n", " 4002ae:\t00 00 \tadd %al,(%rax)\r\n", " 4002b0:\t1a 00 \tsbb (%rax),%al\r\n", " 4002b2:\t00 00 \tadd %al,(%rax)\r\n", " 4002b4:\t12 00 \tadc (%rax),%al\r\n", "\t...\r\n", " 4002c6:\t00 00 \tadd %al,(%rax)\r\n", " 4002c8:\t1f \t(bad) \r\n", " 4002c9:\t00 00 \tadd %al,(%rax)\r\n", " 4002cb:\t00 12 \tadd %dl,(%rdx)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .dynstr:\r\n", "\r\n", "00000000004002e0 <.dynstr>:\r\n", " 4002e0:\t00 5f 5f \tadd %bl,0x5f(%rdi)\r\n", " 4002e3:\t67 6d \tinsl (%dx),%es:(%edi)\r\n", " 4002e5:\t6f \toutsl %ds:(%rsi),(%dx)\r\n", " 4002e6:\t6e \toutsb %ds:(%rsi),(%dx)\r\n", " 4002e7:\t5f \tpop %rdi\r\n", " 4002e8:\t73 74 \tjae 40035e <_init-0x32>\r\n", " 4002ea:\t61 \t(bad) \r\n", " 4002eb:\t72 74 \tjb 400361 <_init-0x2f>\r\n", " 4002ed:\t5f \tpop %rdi\r\n", " 4002ee:\t5f \tpop %rdi\r\n", " 4002ef:\t00 6c 69 62 \tadd %ch,0x62(%rcx,%rbp,2)\r\n", " 4002f3:\t63 2e \tmovslq (%rsi),%ebp\r\n", " 4002f5:\t73 6f \tjae 400366 <_init-0x2a>\r\n", " 4002f7:\t2e 36 00 70 75 \tcs add %dh,%cs:%ss:0x75(%rax)\r\n", " 4002fc:\t74 73 \tje 400371 <_init-0x1f>\r\n", " 4002fe:\t00 5f 5f \tadd %bl,0x5f(%rdi)\r\n", " 400301:\t6c \tinsb (%dx),%es:(%rdi)\r\n", " 400302:\t69 62 63 5f 73 74 61 \timul $0x6174735f,0x63(%rdx),%esp\r\n", " 400309:\t72 74 \tjb 40037f <_init-0x11>\r\n", " 40030b:\t5f \tpop %rdi\r\n", " 40030c:\t6d \tinsl (%dx),%es:(%rdi)\r\n", " 40030d:\t61 \t(bad) \r\n", " 40030e:\t69 6e 00 47 4c 49 42 \timul $0x42494c47,0x0(%rsi),%ebp\r\n", " 400315:\t43 5f \trex.XB pop %r15\r\n", " 400317:\t32 2e \txor (%rsi),%ch\r\n", " 400319:\t32 2e \txor (%rsi),%ch\r\n", " 40031b:\t35 \t.byte 0x35\r\n", "\t...\r\n", "\r\n", "Disassembly of section .gnu.version:\r\n", "\r\n", "000000000040031e <.gnu.version>:\r\n", " 40031e:\t00 00 \tadd %al,(%rax)\r\n", " 400320:\t00 00 \tadd %al,(%rax)\r\n", " 400322:\t02 00 \tadd (%rax),%al\r\n", " 400324:\t02 00 \tadd (%rax),%al\r\n", "\r\n", "Disassembly of section .gnu.version_r:\r\n", "\r\n", "0000000000400328 <.gnu.version_r>:\r\n", " 400328:\t01 00 \tadd %eax,(%rax)\r\n", " 40032a:\t01 00 \tadd %eax,(%rax)\r\n", " 40032c:\t10 00 \tadc %al,(%rax)\r\n", " 40032e:\t00 00 \tadd %al,(%rax)\r\n", " 400330:\t10 00 \tadc %al,(%rax)\r\n", " 400332:\t00 00 \tadd %al,(%rax)\r\n", " 400334:\t00 00 \tadd %al,(%rax)\r\n", " 400336:\t00 00 \tadd %al,(%rax)\r\n", " 400338:\t75 1a \tjne 400354 <_init-0x3c>\r\n", " 40033a:\t69 09 00 00 02 00 \timul $0x20000,(%rcx),%ecx\r\n", " 400340:\t31 00 \txor %eax,(%rax)\r\n", " 400342:\t00 00 \tadd %al,(%rax)\r\n", " 400344:\t00 00 \tadd %al,(%rax)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .rela.dyn:\r\n", "\r\n", "0000000000400348 <.rela.dyn>:\r\n", " 400348:\t48 08 60 00 \trex.W or %spl,0x0(%rax)\r\n", " 40034c:\t00 00 \tadd %al,(%rax)\r\n", " 40034e:\t00 00 \tadd %al,(%rax)\r\n", " 400350:\t06 \t(bad) \r\n", " 400351:\t00 00 \tadd %al,(%rax)\r\n", " 400353:\t00 01 \tadd %al,(%rcx)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .rela.plt:\r\n", "\r\n", "0000000000400360 <.rela.plt>:\r\n", " 400360:\t68 08 60 00 00 \tpushq $0x6008\r\n", " 400365:\t00 00 \tadd %al,(%rax)\r\n", " 400367:\t00 07 \tadd %al,(%rdi)\r\n", " 400369:\t00 00 \tadd %al,(%rax)\r\n", " 40036b:\t00 02 \tadd %al,(%rdx)\r\n", "\t...\r\n", " 400375:\t00 00 \tadd %al,(%rax)\r\n", " 400377:\t00 70 08 \tadd %dh,0x8(%rax)\r\n", " 40037a:\t60 \t(bad) \r\n", " 40037b:\t00 00 \tadd %al,(%rax)\r\n", " 40037d:\t00 00 \tadd %al,(%rax)\r\n", " 40037f:\t00 07 \tadd %al,(%rdi)\r\n", " 400381:\t00 00 \tadd %al,(%rax)\r\n", " 400383:\t00 03 \tadd %al,(%rbx)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .init:\r\n", "\r\n", "0000000000400390 <_init>:\r\n", " 400390:\t48 83 ec 08 \tsub $0x8,%rsp\r\n", " 400394:\te8 73 00 00 00 \tcallq 40040c \r\n", " 400399:\te8 02 01 00 00 \tcallq 4004a0 \r\n", " 40039e:\te8 dd 01 00 00 \tcallq 400580 <__do_global_ctors_aux>\r\n", " 4003a3:\t48 83 c4 08 \tadd $0x8,%rsp\r\n", " 4003a7:\tc3 \tretq \r\n", "\r\n", "Disassembly of section .plt:\r\n", "\r\n", "00000000004003a8 :\r\n", " 4003a8:\tff 35 aa 04 20 00 \tpushq 0x2004aa(%rip) # 600858 <_GLOBAL_OFFSET_TABLE_+0x8>\r\n", " 4003ae:\tff 25 ac 04 20 00 \tjmpq *0x2004ac(%rip) # 600860 <_GLOBAL_OFFSET_TABLE_+0x10>\r\n", " 4003b4:\t0f 1f 40 00 \tnopl 0x0(%rax)\r\n", "\r\n", "00000000004003b8 :\r\n", " 4003b8:\tff 25 aa 04 20 00 \tjmpq *0x2004aa(%rip) # 600868 <_GLOBAL_OFFSET_TABLE_+0x18>\r\n", " 4003be:\t68 00 00 00 00 \tpushq $0x0\r\n", " 4003c3:\te9 e0 ff ff ff \tjmpq 4003a8 <_init+0x18>\r\n", "\r\n", "00000000004003c8 <__libc_start_main@plt>:\r\n", " 4003c8:\tff 25 a2 04 20 00 \tjmpq *0x2004a2(%rip) # 600870 <_GLOBAL_OFFSET_TABLE_+0x20>\r\n", " 4003ce:\t68 01 00 00 00 \tpushq $0x1\r\n", " 4003d3:\te9 d0 ff ff ff \tjmpq 4003a8 <_init+0x18>\r\n", "\r\n", "Disassembly of section .text:\r\n", "\r\n", "00000000004003e0 <_start>:\r\n", " 4003e0:\t31 ed \txor %ebp,%ebp\r\n", " 4003e2:\t49 89 d1 \tmov %rdx,%r9\r\n", " 4003e5:\t5e \tpop %rsi\r\n", " 4003e6:\t48 89 e2 \tmov %rsp,%rdx\r\n", " 4003e9:\t48 83 e4 f0 \tand $0xfffffffffffffff0,%rsp\r\n", " 4003ed:\t50 \tpush %rax\r\n", " 4003ee:\t54 \tpush %rsp\r\n", " 4003ef:\t49 c7 c0 e0 04 40 00 \tmov $0x4004e0,%r8\r\n", " 4003f6:\t48 c7 c1 f0 04 40 00 \tmov $0x4004f0,%rcx\r\n", " 4003fd:\t48 c7 c7 c4 04 40 00 \tmov $0x4004c4,%rdi\r\n", " 400404:\te8 bf ff ff ff \tcallq 4003c8 <__libc_start_main@plt>\r\n", " 400409:\tf4 \thlt \r\n", " 40040a:\t90 \tnop\r\n", " 40040b:\t90 \tnop\r\n", "\r\n", "000000000040040c :\r\n", " 40040c:\t48 83 ec 08 \tsub $0x8,%rsp\r\n", " 400410:\t48 8b 05 31 04 20 00 \tmov 0x200431(%rip),%rax # 600848 <_DYNAMIC+0x190>\r\n", " 400417:\t48 85 c0 \ttest %rax,%rax\r\n", " 40041a:\t74 02 \tje 40041e \r\n", " 40041c:\tff d0 \tcallq *%rax\r\n", " 40041e:\t48 83 c4 08 \tadd $0x8,%rsp\r\n", " 400422:\tc3 \tretq \r\n", " 400423:\t90 \tnop\r\n", " 400424:\t90 \tnop\r\n", " 400425:\t90 \tnop\r\n", " 400426:\t90 \tnop\r\n", " 400427:\t90 \tnop\r\n", " 400428:\t90 \tnop\r\n", " 400429:\t90 \tnop\r\n", " 40042a:\t90 \tnop\r\n", " 40042b:\t90 \tnop\r\n", " 40042c:\t90 \tnop\r\n", " 40042d:\t90 \tnop\r\n", " 40042e:\t90 \tnop\r\n", " 40042f:\t90 \tnop\r\n", "\r\n", "0000000000400430 <__do_global_dtors_aux>:\r\n", " 400430:\t55 \tpush %rbp\r\n", " 400431:\t48 89 e5 \tmov %rsp,%rbp\r\n", " 400434:\t53 \tpush %rbx\r\n", " 400435:\t48 83 ec 08 \tsub $0x8,%rsp\r\n", " 400439:\t80 3d 40 04 20 00 00 \tcmpb $0x0,0x200440(%rip) # 600880 \r\n", " 400440:\t75 4b \tjne 40048d <__do_global_dtors_aux+0x5d>\r\n", " 400442:\tbb a8 06 60 00 \tmov $0x6006a8,%ebx\r\n", " 400447:\t48 8b 05 3a 04 20 00 \tmov 0x20043a(%rip),%rax # 600888 \r\n", " 40044e:\t48 81 eb a0 06 60 00 \tsub $0x6006a0,%rbx\r\n", " 400455:\t48 c1 fb 03 \tsar $0x3,%rbx\r\n", " 400459:\t48 83 eb 01 \tsub $0x1,%rbx\r\n", " 40045d:\t48 39 d8 \tcmp %rbx,%rax\r\n", " 400460:\t73 24 \tjae 400486 <__do_global_dtors_aux+0x56>\r\n", " 400462:\t66 0f 1f 44 00 00 \tnopw 0x0(%rax,%rax,1)\r\n", " 400468:\t48 83 c0 01 \tadd $0x1,%rax\r\n", " 40046c:\t48 89 05 15 04 20 00 \tmov %rax,0x200415(%rip) # 600888 \r\n", " 400473:\tff 14 c5 a0 06 60 00 \tcallq *0x6006a0(,%rax,8)\r\n", " 40047a:\t48 8b 05 07 04 20 00 \tmov 0x200407(%rip),%rax # 600888 \r\n", " 400481:\t48 39 d8 \tcmp %rbx,%rax\r\n", " 400484:\t72 e2 \tjb 400468 <__do_global_dtors_aux+0x38>\r\n", " 400486:\tc6 05 f3 03 20 00 01 \tmovb $0x1,0x2003f3(%rip) # 600880 \r\n", " 40048d:\t48 83 c4 08 \tadd $0x8,%rsp\r\n", " 400491:\t5b \tpop %rbx\r\n", " 400492:\tc9 \tleaveq \r\n", " 400493:\tc3 \tretq \r\n", " 400494:\t66 66 66 2e 0f 1f 84 \tdata32 data32 nopw %cs:0x0(%rax,%rax,1)\r\n", " 40049b:\t00 00 00 00 00 \r\n", "\r\n", "00000000004004a0 :\r\n", " 4004a0:\t48 83 3d 08 02 20 00 \tcmpq $0x0,0x200208(%rip) # 6006b0 <__JCR_END__>\r\n", " 4004a7:\t00 \r\n", " 4004a8:\t55 \tpush %rbp\r\n", " 4004a9:\t48 89 e5 \tmov %rsp,%rbp\r\n", " 4004ac:\t74 12 \tje 4004c0 \r\n", " 4004ae:\tb8 00 00 00 00 \tmov $0x0,%eax\r\n", " 4004b3:\t48 85 c0 \ttest %rax,%rax\r\n", " 4004b6:\t74 08 \tje 4004c0 \r\n", " 4004b8:\tbf b0 06 60 00 \tmov $0x6006b0,%edi\r\n", " 4004bd:\tc9 \tleaveq \r\n", " 4004be:\tff e0 \tjmpq *%rax\r\n", " 4004c0:\tc9 \tleaveq \r\n", " 4004c1:\tc3 \tretq \r\n", " 4004c2:\t90 \tnop\r\n", " 4004c3:\t90 \tnop\r\n", "\r\n", "00000000004004c4
:\r\n", " 4004c4:\t55 \tpush %rbp\r\n", " 4004c5:\t48 89 e5 \tmov %rsp,%rbp\r\n", " 4004c8:\tbf d8 05 40 00 \tmov $0x4005d8,%edi\r\n", " 4004cd:\te8 e6 fe ff ff \tcallq 4003b8 \r\n", " 4004d2:\tb8 00 00 00 00 \tmov $0x0,%eax\r\n", " 4004d7:\tc9 \tleaveq \r\n", " 4004d8:\tc3 \tretq \r\n", " 4004d9:\t90 \tnop\r\n", " 4004da:\t90 \tnop\r\n", " 4004db:\t90 \tnop\r\n", " 4004dc:\t90 \tnop\r\n", " 4004dd:\t90 \tnop\r\n", " 4004de:\t90 \tnop\r\n", " 4004df:\t90 \tnop\r\n", "\r\n", "00000000004004e0 <__libc_csu_fini>:\r\n", " 4004e0:\tf3 c3 \trepz retq \r\n", " 4004e2:\t66 66 66 66 66 2e 0f \tdata32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)\r\n", " 4004e9:\t1f 84 00 00 00 00 00 \r\n", "\r\n", "00000000004004f0 <__libc_csu_init>:\r\n", " 4004f0:\t48 89 6c 24 d8 \tmov %rbp,-0x28(%rsp)\r\n", " 4004f5:\t4c 89 64 24 e0 \tmov %r12,-0x20(%rsp)\r\n", " 4004fa:\t48 8d 2d 8b 01 20 00 \tlea 0x20018b(%rip),%rbp # 60068c <__init_array_end>\r\n", " 400501:\t4c 8d 25 84 01 20 00 \tlea 0x200184(%rip),%r12 # 60068c <__init_array_end>\r\n", " 400508:\t4c 89 6c 24 e8 \tmov %r13,-0x18(%rsp)\r\n", " 40050d:\t4c 89 74 24 f0 \tmov %r14,-0x10(%rsp)\r\n", " 400512:\t4c 89 7c 24 f8 \tmov %r15,-0x8(%rsp)\r\n", " 400517:\t48 89 5c 24 d0 \tmov %rbx,-0x30(%rsp)\r\n", " 40051c:\t48 83 ec 38 \tsub $0x38,%rsp\r\n", " 400520:\t4c 29 e5 \tsub %r12,%rbp\r\n", " 400523:\t41 89 fd \tmov %edi,%r13d\r\n", " 400526:\t49 89 f6 \tmov %rsi,%r14\r\n", " 400529:\t48 c1 fd 03 \tsar $0x3,%rbp\r\n", " 40052d:\t49 89 d7 \tmov %rdx,%r15\r\n", " 400530:\te8 5b fe ff ff \tcallq 400390 <_init>\r\n", " 400535:\t48 85 ed \ttest %rbp,%rbp\r\n", " 400538:\t74 1c \tje 400556 <__libc_csu_init+0x66>\r\n", " 40053a:\t31 db \txor %ebx,%ebx\r\n", " 40053c:\t0f 1f 40 00 \tnopl 0x0(%rax)\r\n", " 400540:\t4c 89 fa \tmov %r15,%rdx\r\n", " 400543:\t4c 89 f6 \tmov %r14,%rsi\r\n", " 400546:\t44 89 ef \tmov %r13d,%edi\r\n", " 400549:\t41 ff 14 dc \tcallq *(%r12,%rbx,8)\r\n", " 40054d:\t48 83 c3 01 \tadd $0x1,%rbx\r\n", " 400551:\t48 39 eb \tcmp %rbp,%rbx\r\n", " 400554:\t72 ea \tjb 400540 <__libc_csu_init+0x50>\r\n", " 400556:\t48 8b 5c 24 08 \tmov 0x8(%rsp),%rbx\r\n", " 40055b:\t48 8b 6c 24 10 \tmov 0x10(%rsp),%rbp\r\n", " 400560:\t4c 8b 64 24 18 \tmov 0x18(%rsp),%r12\r\n", " 400565:\t4c 8b 6c 24 20 \tmov 0x20(%rsp),%r13\r\n", " 40056a:\t4c 8b 74 24 28 \tmov 0x28(%rsp),%r14\r\n", " 40056f:\t4c 8b 7c 24 30 \tmov 0x30(%rsp),%r15\r\n", " 400574:\t48 83 c4 38 \tadd $0x38,%rsp\r\n", " 400578:\tc3 \tretq \r\n", " 400579:\t90 \tnop\r\n", " 40057a:\t90 \tnop\r\n", " 40057b:\t90 \tnop\r\n", " 40057c:\t90 \tnop\r\n", " 40057d:\t90 \tnop\r\n", " 40057e:\t90 \tnop\r\n", " 40057f:\t90 \tnop\r\n", "\r\n", "0000000000400580 <__do_global_ctors_aux>:\r\n", " 400580:\t55 \tpush %rbp\r\n", " 400581:\t48 89 e5 \tmov %rsp,%rbp\r\n", " 400584:\t53 \tpush %rbx\r\n", " 400585:\t48 83 ec 08 \tsub $0x8,%rsp\r\n", " 400589:\t48 8b 05 00 01 20 00 \tmov 0x200100(%rip),%rax # 600690 <__CTOR_LIST__>\r\n", " 400590:\t48 83 f8 ff \tcmp $0xffffffffffffffff,%rax\r\n", " 400594:\t74 19 \tje 4005af <__do_global_ctors_aux+0x2f>\r\n", " 400596:\tbb 90 06 60 00 \tmov $0x600690,%ebx\r\n", " 40059b:\t0f 1f 44 00 00 \tnopl 0x0(%rax,%rax,1)\r\n", " 4005a0:\t48 83 eb 08 \tsub $0x8,%rbx\r\n", " 4005a4:\tff d0 \tcallq *%rax\r\n", " 4005a6:\t48 8b 03 \tmov (%rbx),%rax\r\n", " 4005a9:\t48 83 f8 ff \tcmp $0xffffffffffffffff,%rax\r\n", " 4005ad:\t75 f1 \tjne 4005a0 <__do_global_ctors_aux+0x20>\r\n", " 4005af:\t48 83 c4 08 \tadd $0x8,%rsp\r\n", " 4005b3:\t5b \tpop %rbx\r\n", " 4005b4:\tc9 \tleaveq \r\n", " 4005b5:\tc3 \tretq \r\n", " 4005b6:\t90 \tnop\r\n", " 4005b7:\t90 \tnop\r\n", "\r\n", "Disassembly of section .fini:\r\n", "\r\n", "00000000004005b8 <_fini>:\r\n", " 4005b8:\t48 83 ec 08 \tsub $0x8,%rsp\r\n", " 4005bc:\te8 6f fe ff ff \tcallq 400430 <__do_global_dtors_aux>\r\n", " 4005c1:\t48 83 c4 08 \tadd $0x8,%rsp\r\n", " 4005c5:\tc3 \tretq \r\n", "\r\n", "Disassembly of section .rodata:\r\n", "\r\n", "00000000004005c8 <_IO_stdin_used>:\r\n", " 4005c8:\t01 00 \tadd %eax,(%rax)\r\n", " 4005ca:\t02 00 \tadd (%rax),%al\r\n", " 4005cc:\t00 00 \tadd %al,(%rax)\r\n", "\t...\r\n", "\r\n", "00000000004005d0 <__dso_handle>:\r\n", "\t...\r\n", " 4005d8:\t54 \tpush %rsp\r\n", " 4005d9:\t65 \tgs\r\n", " 4005da:\t73 74 \tjae 400650 <__dso_handle+0x80>\r\n", " 4005dc:\t69 6e 67 20 31 2c 20 \timul $0x202c3120,0x67(%rsi),%ebp\r\n", " 4005e3:\t32 2c 20 \txor (%rax,%riz,1),%ch\r\n", " 4005e6:\t33 2e \txor (%rsi),%ebp\r\n", " 4005e8:\t2e \tcs\r\n", " 4005e9:\t2e \tcs\r\n", "\t...\r\n", "\r\n", "Disassembly of section .eh_frame_hdr:\r\n", "\r\n", "00000000004005ec <.eh_frame_hdr>:\r\n", " 4005ec:\t01 1b \tadd %ebx,(%rbx)\r\n", " 4005ee:\t03 3b \tadd (%rbx),%edi\r\n", " 4005f0:\t20 00 \tand %al,(%rax)\r\n", " 4005f2:\t00 00 \tadd %al,(%rax)\r\n", " 4005f4:\t03 00 \tadd (%rax),%eax\r\n", " 4005f6:\t00 00 \tadd %al,(%rax)\r\n", " 4005f8:\td8 fe \tfdivr %st(6),%st\r\n", " 4005fa:\tff \t(bad) \r\n", " 4005fb:\tff \t(bad) \r\n", " 4005fc:\t3c 00 \tcmp $0x0,%al\r\n", " 4005fe:\t00 00 \tadd %al,(%rax)\r\n", " 400600:\tf4 \thlt \r\n", " 400601:\tfe \t(bad) \r\n", " 400602:\tff \t(bad) \r\n", " 400603:\tff 5c 00 00 \tlcallq *0x0(%rax,%rax,1)\r\n", " 400607:\t00 04 ff \tadd %al,(%rdi,%rdi,8)\r\n", " 40060a:\tff \t(bad) \r\n", " 40060b:\tff 74 00 00 \tpushq 0x0(%rax,%rax,1)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .eh_frame:\r\n", "\r\n", "0000000000400610 <__FRAME_END__-0x78>:\r\n", " 400610:\t14 00 \tadc $0x0,%al\r\n", " 400612:\t00 00 \tadd %al,(%rax)\r\n", " 400614:\t00 00 \tadd %al,(%rax)\r\n", " 400616:\t00 00 \tadd %al,(%rax)\r\n", " 400618:\t01 7a 52 \tadd %edi,0x52(%rdx)\r\n", " 40061b:\t00 01 \tadd %al,(%rcx)\r\n", " 40061d:\t78 10 \tjs 40062f <__dso_handle+0x5f>\r\n", " 40061f:\t01 1b \tadd %ebx,(%rbx)\r\n", " 400621:\t0c 07 \tor $0x7,%al\r\n", " 400623:\t08 90 01 00 00 1c \tor %dl,0x1c000001(%rax)\r\n", " 400629:\t00 00 \tadd %al,(%rax)\r\n", " 40062b:\t00 1c 00 \tadd %bl,(%rax,%rax,1)\r\n", " 40062e:\t00 00 \tadd %al,(%rax)\r\n", " 400630:\t94 \txchg %eax,%esp\r\n", " 400631:\tfe \t(bad) \r\n", " 400632:\tff \t(bad) \r\n", " 400633:\tff 15 00 00 00 00 \tcallq *0x0(%rip) # 400639 <__dso_handle+0x69>\r\n", " 400639:\t41 0e \trex.B (bad) \r\n", " 40063b:\t10 86 02 43 0d 06 \tadc %al,0x60d4302(%rsi)\r\n", " 400641:\t50 \tpush %rax\r\n", " 400642:\t0c 07 \tor $0x7,%al\r\n", " 400644:\t08 00 \tor %al,(%rax)\r\n", " 400646:\t00 00 \tadd %al,(%rax)\r\n", " 400648:\t14 00 \tadc $0x0,%al\r\n", " 40064a:\t00 00 \tadd %al,(%rax)\r\n", " 40064c:\t3c 00 \tcmp $0x0,%al\r\n", " 40064e:\t00 00 \tadd %al,(%rax)\r\n", " 400650:\t90 \tnop\r\n", " 400651:\tfe \t(bad) \r\n", " 400652:\tff \t(bad) \r\n", " 400653:\tff 02 \tincl (%rdx)\r\n", "\t...\r\n", " 40065d:\t00 00 \tadd %al,(%rax)\r\n", " 40065f:\t00 24 00 \tadd %ah,(%rax,%rax,1)\r\n", " 400662:\t00 00 \tadd %al,(%rax)\r\n", " 400664:\t54 \tpush %rsp\r\n", " 400665:\t00 00 \tadd %al,(%rax)\r\n", " 400667:\t00 88 fe ff ff 89 \tadd %cl,-0x76000002(%rax)\r\n", " 40066d:\t00 00 \tadd %al,(%rax)\r\n", " 40066f:\t00 00 \tadd %al,(%rax)\r\n", " 400671:\t51 \tpush %rcx\r\n", " 400672:\t8c 05 86 06 5f 0e \tmov %es,0xe5f0686(%rip) # e9f0cfe <_end+0xe3f046e>\r\n", " 400678:\t40 83 07 8f \trex addl $0xffffffffffffff8f,(%rdi)\r\n", " 40067c:\t02 8e 03 8d 04 02 \tadd 0x2048d03(%rsi),%cl\r\n", " 400682:\t58 \tpop %rax\r\n", " 400683:\t0e \t(bad) \r\n", " 400684:\t08 00 \tor %al,(%rax)\r\n", "\t...\r\n", "\r\n", "0000000000400688 <__FRAME_END__>:\r\n", " 400688:\t00 00 \tadd %al,(%rax)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .ctors:\r\n", "\r\n", "0000000000600690 <__CTOR_LIST__>:\r\n", " 600690:\tff \t(bad) \r\n", " 600691:\tff \t(bad) \r\n", " 600692:\tff \t(bad) \r\n", " 600693:\tff \t(bad) \r\n", " 600694:\tff \t(bad) \r\n", " 600695:\tff \t(bad) \r\n", " 600696:\tff \t(bad) \r\n", " 600697:\tff 00 \tincl (%rax)\r\n", "\r\n", "0000000000600698 <__CTOR_END__>:\r\n", "\t...\r\n", "\r\n", "Disassembly of section .dtors:\r\n", "\r\n", "00000000006006a0 <__DTOR_LIST__>:\r\n", " 6006a0:\tff \t(bad) \r\n", " 6006a1:\tff \t(bad) \r\n", " 6006a2:\tff \t(bad) \r\n", " 6006a3:\tff \t(bad) \r\n", " 6006a4:\tff \t(bad) \r\n", " 6006a5:\tff \t(bad) \r\n", " 6006a6:\tff \t(bad) \r\n", " 6006a7:\tff 00 \tincl (%rax)\r\n", "\r\n", "00000000006006a8 <__DTOR_END__>:\r\n", "\t...\r\n", "\r\n", "Disassembly of section .jcr:\r\n", "\r\n", "00000000006006b0 <__JCR_END__>:\r\n", "\t...\r\n", "\r\n", "Disassembly of section .dynamic:\r\n", "\r\n", "00000000006006b8 <_DYNAMIC>:\r\n", " 6006b8:\t01 00 \tadd %eax,(%rax)\r\n", " 6006ba:\t00 00 \tadd %al,(%rax)\r\n", " 6006bc:\t00 00 \tadd %al,(%rax)\r\n", " 6006be:\t00 00 \tadd %al,(%rax)\r\n", " 6006c0:\t10 00 \tadc %al,(%rax)\r\n", " 6006c2:\t00 00 \tadd %al,(%rax)\r\n", " 6006c4:\t00 00 \tadd %al,(%rax)\r\n", " 6006c6:\t00 00 \tadd %al,(%rax)\r\n", " 6006c8:\t0c 00 \tor $0x0,%al\r\n", " 6006ca:\t00 00 \tadd %al,(%rax)\r\n", " 6006cc:\t00 00 \tadd %al,(%rax)\r\n", " 6006ce:\t00 00 \tadd %al,(%rax)\r\n", " 6006d0:\t90 \tnop\r\n", " 6006d1:\t03 40 00 \tadd 0x0(%rax),%eax\r\n", " 6006d4:\t00 00 \tadd %al,(%rax)\r\n", " 6006d6:\t00 00 \tadd %al,(%rax)\r\n", " 6006d8:\t0d 00 00 00 00 \tor $0x0,%eax\r\n", " 6006dd:\t00 00 \tadd %al,(%rax)\r\n", " 6006df:\t00 b8 05 40 00 00 \tadd %bh,0x4005(%rax)\r\n", " 6006e5:\t00 00 \tadd %al,(%rax)\r\n", " 6006e7:\t00 f5 \tadd %dh,%ch\r\n", " 6006e9:\tfe \t(bad) \r\n", " 6006ea:\tff 6f 00 \tljmpq *0x0(%rdi)\r\n", " 6006ed:\t00 00 \tadd %al,(%rax)\r\n", " 6006ef:\t00 60 02 \tadd %ah,0x2(%rax)\r\n", " 6006f2:\t40 00 00 \tadd %al,(%rax)\r\n", " 6006f5:\t00 00 \tadd %al,(%rax)\r\n", " 6006f7:\t00 05 00 00 00 00 \tadd %al,0x0(%rip) # 6006fd <_DYNAMIC+0x45>\r\n", " 6006fd:\t00 00 \tadd %al,(%rax)\r\n", " 6006ff:\t00 e0 \tadd %ah,%al\r\n", " 600701:\t02 40 00 \tadd 0x0(%rax),%al\r\n", " 600704:\t00 00 \tadd %al,(%rax)\r\n", " 600706:\t00 00 \tadd %al,(%rax)\r\n", " 600708:\t06 \t(bad) \r\n", " 600709:\t00 00 \tadd %al,(%rax)\r\n", " 60070b:\t00 00 \tadd %al,(%rax)\r\n", " 60070d:\t00 00 \tadd %al,(%rax)\r\n", " 60070f:\t00 80 02 40 00 00 \tadd %al,0x4002(%rax)\r\n", " 600715:\t00 00 \tadd %al,(%rax)\r\n", " 600717:\t00 0a \tadd %cl,(%rdx)\r\n", " 600719:\t00 00 \tadd %al,(%rax)\r\n", " 60071b:\t00 00 \tadd %al,(%rax)\r\n", " 60071d:\t00 00 \tadd %al,(%rax)\r\n", " 60071f:\t00 3d 00 00 00 00 \tadd %bh,0x0(%rip) # 600725 <_DYNAMIC+0x6d>\r\n", " 600725:\t00 00 \tadd %al,(%rax)\r\n", " 600727:\t00 0b \tadd %cl,(%rbx)\r\n", " 600729:\t00 00 \tadd %al,(%rax)\r\n", " 60072b:\t00 00 \tadd %al,(%rax)\r\n", " 60072d:\t00 00 \tadd %al,(%rax)\r\n", " 60072f:\t00 18 \tadd %bl,(%rax)\r\n", " 600731:\t00 00 \tadd %al,(%rax)\r\n", " 600733:\t00 00 \tadd %al,(%rax)\r\n", " 600735:\t00 00 \tadd %al,(%rax)\r\n", " 600737:\t00 15 00 00 00 00 \tadd %dl,0x0(%rip) # 60073d <_DYNAMIC+0x85>\r\n", "\t...\r\n", " 600745:\t00 00 \tadd %al,(%rax)\r\n", " 600747:\t00 03 \tadd %al,(%rbx)\r\n", " 600749:\t00 00 \tadd %al,(%rax)\r\n", " 60074b:\t00 00 \tadd %al,(%rax)\r\n", " 60074d:\t00 00 \tadd %al,(%rax)\r\n", " 60074f:\t00 50 08 \tadd %dl,0x8(%rax)\r\n", " 600752:\t60 \t(bad) \r\n", " 600753:\t00 00 \tadd %al,(%rax)\r\n", " 600755:\t00 00 \tadd %al,(%rax)\r\n", " 600757:\t00 02 \tadd %al,(%rdx)\r\n", " 600759:\t00 00 \tadd %al,(%rax)\r\n", " 60075b:\t00 00 \tadd %al,(%rax)\r\n", " 60075d:\t00 00 \tadd %al,(%rax)\r\n", " 60075f:\t00 30 \tadd %dh,(%rax)\r\n", " 600761:\t00 00 \tadd %al,(%rax)\r\n", " 600763:\t00 00 \tadd %al,(%rax)\r\n", " 600765:\t00 00 \tadd %al,(%rax)\r\n", " 600767:\t00 14 00 \tadd %dl,(%rax,%rax,1)\r\n", " 60076a:\t00 00 \tadd %al,(%rax)\r\n", " 60076c:\t00 00 \tadd %al,(%rax)\r\n", " 60076e:\t00 00 \tadd %al,(%rax)\r\n", " 600770:\t07 \t(bad) \r\n", " 600771:\t00 00 \tadd %al,(%rax)\r\n", " 600773:\t00 00 \tadd %al,(%rax)\r\n", " 600775:\t00 00 \tadd %al,(%rax)\r\n", " 600777:\t00 17 \tadd %dl,(%rdi)\r\n", " 600779:\t00 00 \tadd %al,(%rax)\r\n", " 60077b:\t00 00 \tadd %al,(%rax)\r\n", " 60077d:\t00 00 \tadd %al,(%rax)\r\n", " 60077f:\t00 60 03 \tadd %ah,0x3(%rax)\r\n", " 600782:\t40 00 00 \tadd %al,(%rax)\r\n", " 600785:\t00 00 \tadd %al,(%rax)\r\n", " 600787:\t00 07 \tadd %al,(%rdi)\r\n", " 600789:\t00 00 \tadd %al,(%rax)\r\n", " 60078b:\t00 00 \tadd %al,(%rax)\r\n", " 60078d:\t00 00 \tadd %al,(%rax)\r\n", " 60078f:\t00 48 03 \tadd %cl,0x3(%rax)\r\n", " 600792:\t40 00 00 \tadd %al,(%rax)\r\n", " 600795:\t00 00 \tadd %al,(%rax)\r\n", " 600797:\t00 08 \tadd %cl,(%rax)\r\n", " 600799:\t00 00 \tadd %al,(%rax)\r\n", " 60079b:\t00 00 \tadd %al,(%rax)\r\n", " 60079d:\t00 00 \tadd %al,(%rax)\r\n", " 60079f:\t00 18 \tadd %bl,(%rax)\r\n", " 6007a1:\t00 00 \tadd %al,(%rax)\r\n", " 6007a3:\t00 00 \tadd %al,(%rax)\r\n", " 6007a5:\t00 00 \tadd %al,(%rax)\r\n", " 6007a7:\t00 09 \tadd %cl,(%rcx)\r\n", " 6007a9:\t00 00 \tadd %al,(%rax)\r\n", " 6007ab:\t00 00 \tadd %al,(%rax)\r\n", " 6007ad:\t00 00 \tadd %al,(%rax)\r\n", " 6007af:\t00 18 \tadd %bl,(%rax)\r\n", " 6007b1:\t00 00 \tadd %al,(%rax)\r\n", " 6007b3:\t00 00 \tadd %al,(%rax)\r\n", " 6007b5:\t00 00 \tadd %al,(%rax)\r\n", " 6007b7:\t00 fe \tadd %bh,%dh\r\n", " 6007b9:\tff \t(bad) \r\n", " 6007ba:\tff 6f 00 \tljmpq *0x0(%rdi)\r\n", " 6007bd:\t00 00 \tadd %al,(%rax)\r\n", " 6007bf:\t00 28 \tadd %ch,(%rax)\r\n", " 6007c1:\t03 40 00 \tadd 0x0(%rax),%eax\r\n", " 6007c4:\t00 00 \tadd %al,(%rax)\r\n", " 6007c6:\t00 00 \tadd %al,(%rax)\r\n", " 6007c8:\tff \t(bad) \r\n", " 6007c9:\tff \t(bad) \r\n", " 6007ca:\tff 6f 00 \tljmpq *0x0(%rdi)\r\n", " 6007cd:\t00 00 \tadd %al,(%rax)\r\n", " 6007cf:\t00 01 \tadd %al,(%rcx)\r\n", " 6007d1:\t00 00 \tadd %al,(%rax)\r\n", " 6007d3:\t00 00 \tadd %al,(%rax)\r\n", " 6007d5:\t00 00 \tadd %al,(%rax)\r\n", " 6007d7:\t00 f0 \tadd %dh,%al\r\n", " 6007d9:\tff \t(bad) \r\n", " 6007da:\tff 6f 00 \tljmpq *0x0(%rdi)\r\n", " 6007dd:\t00 00 \tadd %al,(%rax)\r\n", " 6007df:\t00 1e \tadd %bl,(%rsi)\r\n", " 6007e1:\t03 40 00 \tadd 0x0(%rax),%eax\r\n", "\t...\r\n", "\r\n", "Disassembly of section .got:\r\n", "\r\n", "0000000000600848 <.got>:\r\n", "\t...\r\n", "\r\n", "Disassembly of section .got.plt:\r\n", "\r\n", "0000000000600850 <_GLOBAL_OFFSET_TABLE_>:\r\n", " 600850:\tb8 06 60 00 00 \tmov $0x6006,%eax\r\n", "\t...\r\n", " 600865:\t00 00 \tadd %al,(%rax)\r\n", " 600867:\t00 be 03 40 00 00 \tadd %bh,0x4003(%rsi)\r\n", " 60086d:\t00 00 \tadd %al,(%rax)\r\n", " 60086f:\t00 ce \tadd %cl,%dh\r\n", " 600871:\t03 40 00 \tadd 0x0(%rax),%eax\r\n", " 600874:\t00 00 \tadd %al,(%rax)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .data:\r\n", "\r\n", "0000000000600878 <__data_start>:\r\n", " 600878:\t00 00 \tadd %al,(%rax)\r\n", "\t...\r\n", "\r\n", "Disassembly of section .bss:\r\n", "\r\n", "0000000000600880 :\r\n", "\t...\r\n", "\r\n", "0000000000600888 :\r\n", "\t...\r\n", "\r\n", "Disassembly of section .comment:\r\n", "\r\n", "0000000000000000 <.comment>:\r\n", " 0:\t47 \trex.RXB\r\n", " 1:\t43 \trex.XB\r\n", " 2:\t43 3a 20 \trex.XB cmp (%r8),%spl\r\n", " 5:\t28 47 4e \tsub %al,0x4e(%rdi)\r\n", " 8:\t55 \tpush %rbp\r\n", " 9:\t29 20 \tsub %esp,(%rax)\r\n", " b:\t34 2e \txor $0x2e,%al\r\n", " d:\t34 2e \txor $0x2e,%al\r\n", " f:\t36 20 32 \tand %dh,%ss:(%rdx)\r\n", " 12:\t30 31 \txor %dh,(%rcx)\r\n", " 14:\t32 30 \txor (%rax),%dh\r\n", " 16:\t33 30 \txor (%rax),%esi\r\n", " 18:\t35 20 28 52 65 \txor $0x65522820,%eax\r\n", " 1d:\t64 20 48 61 \tand %cl,%fs:0x61(%rax)\r\n", " 21:\t74 20 \tje 43 <_init-0x40034d>\r\n", " 23:\t34 2e \txor $0x2e,%al\r\n", " 25:\t34 2e \txor $0x2e,%al\r\n", " 27:\t36 \tss\r\n", " 28:\t2d \t.byte 0x2d\r\n", " 29:\t34 29 \txor $0x29,%al\r\n", "\t...\r\n", "\n" ] } ], "source": [ "! objdump -D Test1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 6. C with the LC-3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6.1 Setup" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will change the system path so that you can access the lc3 compiler. This adds the path /opt/lcc to the bash system search variable, PATH." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We use the `%%shell` magic to indicate that this cell is a bash shell script:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%shell\n", "\n", "export PATH=/opt/lcc:$PATH" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**NOTE**: as it is a one-liner, we could have also typed:\n", "\n", "```bash\n", "! export PATH=/opt/lcc:$PATH\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The change to the PATH bash shell environment variable will be retained on subsequent calls in the shell." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/opt/lcc:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/maui/sbin:/usr/local/maui/bin:/opt/pssc/bin:/opt/openmpi/bin:/opt/torque/bin:/opt/torque/sbin:/root/bin:/opt/pssc/bin:/opt/openmpi/bin:/opt/torque/bin:/opt/torque/sbin:/opt/pssc/bin:/opt/openmpi/bin:/opt/torque/bin:/opt/torque/sbin\r\n", "\n" ] } ], "source": [ "%%shell\n", "\n", "echo $PATH" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6.2 Creating a C Program" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "```c\n", "#include \n", "\n", "/* A simple C program to test the LC-3 compiler */\n", "\n", "void main() {\n", " int a, b;\n", "\n", " a = 5;\n", " b = a * a + 3;\n", " printf(\"Result = %d\\n\", b);\n", "} \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "stdio.h is a \"header\" file that contains the signatures for the standard IO functions. These are defined in these ASM files:\n", "\n", "* [getchar.asm](https://athena.brynmawr.edu/jupyter/hub/dblank/public/CS240%20Computer%20Organization/2015-Fall/Notes/getchar.asm) \n", "* [scanf.asm](https://athena.brynmawr.edu/jupyter/hub/dblank/public/CS240%20Computer%20Organization/2015-Fall/Notes/scanf.asm)\n", "* [printf.asm](https://athena.brynmawr.edu/jupyter/hub/dblank/public/CS240%20Computer%20Organization/2015-Fall/Notes/printf.asm) \n", "* [stdio.asm](https://athena.brynmawr.edu/jupyter/hub/dblank/public/CS240%20Computer%20Organization/2015-Fall/Notes/stdio.asm)\n", "* [putchar.asm](https://athena.brynmawr.edu/jupyter/hub/dblank/public/CS240%20Computer%20Organization/2015-Fall/Notes/putchar.asm)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created file '/home/dblank/public_html/CS240 Computer Organization/2015-Fall/Notes/Testme.c'.\n" ] } ], "source": [ "%%file Testme.c\n", "\n", "#include \n", "\n", "/* A simple C program to test the LC-3 compiler */\n", "\n", "void main() {\n", " int a, b;\n", "\n", " a = 5;\n", " b = a * a + 3;\n", " printf(\"Result = %d\\n\", b);\n", "} \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6.3 Compile the C Program" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now use the `lcc` LC-3 C Compiler to compile the C source code into an executable (.obj file, in LC-3).\n", "\n", "**NOTE**: you can also just do `! lcc -o Testme.obj Testme.c`" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cpp: Testme.c:12 No newline at end of file\r\n", "STARTING PASS 1\r\n", "0 errors found in first pass.\r\n", "STARTING PASS 2\r\n", "0 errors found in second pass.\r\n", "\n" ] } ], "source": [ "%%shell\n", "\n", "lcc -o Testme.obj Testme.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6.4 Examine the Assembly Language" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When creating a executable, the C Compiler will first create an `.asm` file from the C source:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%load Testme.asm" ] }, { "cell_type": "code", "execution_count": 205, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Warning: Possible overflow of immediate: -16 at line 458\n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Assembled! Use %dis or %dump to examine.\n" ] } ], "source": [ ".Orig x3000\n", "INIT_CODE\n", "LEA R6, #-1\n", "ADD R5, R6, #0\n", "ADD R6, R6, R6\n", "ADD R6, R6, R6\n", "ADD R6, R6, R5\n", "ADD R6, R6, #-1\n", "ADD R5, R5, R5\n", "ADD R5, R6, #0\n", "LD R4, GLOBAL_DATA_POINTER\n", "LD R7, GLOBAL_MAIN_POINTER\n", "jsrr R7\n", "HALT\n", "\n", "GLOBAL_DATA_POINTER .FILL GLOBAL_DATA_START\n", "GLOBAL_MAIN_POINTER .FILL main\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;main;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", "main\n", "ADD R6, R6, #-2\n", "STR R7, R6, #0\n", "ADD R6, R6, #-1\n", "STR R5, R6, #0\n", "ADD R5, R6, #-1\n", "\n", "ADD R6, R6, #-2\n", "ADD R7, R4, #15\n", "ADD R7, R7, #2\n", "ldr R7, R7, #0\n", "str R7, R5, #0\n", "ldr R7, R5, #0\n", "ADD R6, R6, #-1\n", "STR R0, R6, #0\n", "ADD R0, R7, #0\n", "ADD R6, R6, #-1\n", "STR R1, R6, #0\n", "ADD R6, R6, #-1\n", "STR R7, R6, #0\n", "AND R1, R1, #0\n", "ADD R7, R7, #0\n", "BRz L6\n", "BRp L5\n", "NOT R7, R7\n", "ADD R7, R7, #1\n", "L5\n", "ADD R1, R1, R0\n", "ADD R7, R7, #-1\n", "BRnp L5\n", "L6\n", "LDR R7, R6, #0\n", "ADD R6, R6, #1\n", "ADD R7, R7, #0\n", "BRzp L7\n", "NOT R1, R1\n", "ADD R1, R1, #1\n", "L7\n", ";bef epilogue x=1 y=0 z=7\n", "ADD R7, R1, #0\n", "LDR R1, R6, #0\n", "ADD R6, R6, #1\n", "LDR R0, R6, #0\n", "ADD R6, R6, #1\n", ";aft epilogue x=1 y=0 z=7\n", "ADD R3, R4, #15\n", "ADD R3, R3, #1\n", "ldr R3, R3, #0\n", "add R7, R7, R3\n", "str R7, R5, #-1\n", "ldr R7, R5, #-1\n", "ADD R6, R6, #-1\n", "STR R7, R6, #0\n", "ADD R7, R4, #3\n", "ADD R6, R6, #-1\n", "STR R7, R6, #0\n", "ADD R0, R4, #2\n", "LDR R0, R0, #0\n", "jsrr R0\n", "lc3_L1_Testme\n", "STR R7, R5, #3\n", "ADD R6, R5, #1\n", "LDR R5, R6, #0\n", "ADD R6, R6, #1\n", "LDR R7, R6, #0\n", "ADD R6, R6, #1\n", "RET\n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \n", ";\tvoid scanf(const char *format, ...) \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \n", "\n", "SCANF_PERCENT .FILL -37\n", "SCANF_C .FILL -99\n", "SCANF_D .FILL -100\n", "SCANF_S .FILL -115 \n", "SCANF_0 .FILL -48 \n", "SCANF_9 .FILL -57 \n", "SCANF_MINUS .FILL -45 \n", "SCANF_BUF .BLKW 6\n", " \n", "lc3_scanf \n", "ADD R6, R6, #-2 \n", "STR R7, R6, #0 \n", " \n", "ADD R6, R6, #-1\t\t;save R5 = bp \n", "STR R5, R6, #0\t\t \n", "ADD R5, R6, #-1 \n", " \n", "ADD R6, R6, #-1\t\t;save R4 = gp \n", "STR R4, R6, #0 \n", " \n", "ADD R5, R5, #4\t\t;cheating with the bp (no longer bp) \n", "LDR R4, R5, #0\t\t;got addr of format string \n", " \n", "\n", " \n", "\n", "SCANF_LOOP\t;outer loop, R0=tmp register for use with GETC \n", "\t\t\t;R2 holds either cur letter of format string or \n", "\t\t\t;current addr to store a char, dec, or string \n", " \n", " \n", " \n", "LDR R2, R4, #0 \n", " \n", "ADD R2, R2, #0\t\t;End of format string? (0x0000) \n", "BRz SCANF_DONE\n", " \n", "LD R1, SCANF_PERCENT\n", "ADD R0, R2, #0 \n", "ADD R0, R0, R1\t\t\n", "BRnp SCANF_MATCHCHAR\t\t ;% not found\n", " \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;% found! \n", "ADD R4, R4, #1\t\t;R4 points to next char of format string \n", "LDR R2, R4, #0 \n", " \n", "LD R1, SCANF_C\n", "ADD R0, R2, #0\t\t;next char = c? \n", "ADD R0, R0, R1 \n", "BRnp SCANF_CHECKD \n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%c found\n", "ADD R5, R5, #1 \n", "LDR R2, R5, #0\t\t;R2 has addr for char to be read into \n", "\n", "GETC \n", "OUT\n", "STR R0, R2, #0 \n", " \n", "ADD R4, R4, #1 \n", "BRnzp SCANF_LOOP\n", " \n", "SCANF_CHECKD \n", ";is it %d? \n", "LD R1, SCANF_D\n", "ADD R0, R2, #0 \n", "ADD R0, R0, R1 \n", "BRnp SCANF_STR \n", " \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%d found\n", ";consider using vars to store reg\n", ";registers 0,1,2,3,7 available as tmp regs\n", " \n", " \n", "ADD R6, R6, #-1\t\t;saving current ptr into format string \n", "STR R4, R6, #0 \n", " \n", ";ADD R6, R6, #-7\t\t ;making 7byte buffer for ascbin \n", ";ADD R4, R6, #0\t\t ;ptr into that buffer \n", "LEA R4, SCANF_BUF \n", "LD R2, SCANF_0\n", "LD R1, SCANF_9\n", " \n", "SCANF_SCANNUM \n", " \n", "GETC \n", "OUT\n", "STR R0, R4, #0\t\t;Reading and storing typed char \n", " \n", "ADD R0, R2, R0 \n", "BRZP SCANF_CHECKEDLOWER \n", "\n", "LDR R0, R4, #0 \n", "LD R7, SCANF_MINUS\n", "ADD R0, R0, R7\n", "BRz SCANF_CHECKEDLOWER\n", " \n", "LEA R0, SCANF_BUF \n", "NOT R0, R0 \n", "ADD R0, R0, #1 \n", "ADD R0, R4, R0 \n", "BRz SCANF_SCANNUM\t ;buffer is empty and wrong char, go to error?\n", " \n", "ADD R4, R4, #-1 \t\t;fixme: need to save this char\n", "BRnzp SCANF_NUMDONE \n", " \n", " \n", "SCANF_CHECKEDLOWER \n", " \n", "LDR R0, R4, #0 \n", "ADD R0, R1, R0 \n", "BRNZ SCANF_CHECKEDUPPER \n", " \n", "LEA R0, SCANF_BUF \n", "NOT R0, R0 \n", "ADD R0, R0, #1 \n", "ADD R0, R4, R0 \n", "BRz SCANF_SCANNUM\t ;buffer is empty and wrong char, go to error?\n", " \n", "ADD R4, R4, #-1 \t\t;fixme: need to save this char\n", "BRnzp SCANF_NUMDONE \n", " \n", "SCANF_CHECKEDUPPER \n", " \n", "LEA R0, SCANF_BUF \n", "ADD R0, R0, #5 \n", "\n", "NOT R0, R0 \n", "ADD R0, R0, #1 \n", "ADD R0, R4, R0 \n", "BRz SCANF_NUMDONE\t ;buffer is full \n", " \n", "ADD R4, R4, #1 \n", "BRnzp SCANF_SCANNUM \n", " \n", "SCANF_NUMDONE \n", "\t\t ;R4 points to last char entered in (ones digit) \n", " \n", ";ADD R7, R6, #0\t ;R7 points to the highest order digit \n", "LEA R7, SCANF_BUF \n", "LD R0, SCANF_MINUS\n", "LD R1, SCANF_BUF\n", "ADD R0, R0, R1\n", "BRnp SCANF_NOTMINUS\n", "ADD R7, R7, #1 \t;fixme check for - -\n", "\n", "SCANF_NOTMINUS\n", " \n", ";STR R2, R6, #-1 ;psuedo stored -'0' on stack \n", "AND R2, R2, #0\t ;R2 acts as the acumulator \n", " \n", "SCANF_CALC \n", " \n", "LDR R0, R7, #0 \n", ";LDR R1, R6, #-1 \n", "LD R1, SCANF_0\n", "ADD R0, R0, R1 \n", "ADD R2, R2, R0 \n", " \n", "NOT R1, R7 \n", "ADD R1, R1, #1 \n", "ADD R1, R4, R1 \n", "BRz SCANF_CALCDONE \n", "\t\t\t ;R2 = 10*R2 \n", "ADD R0, R2, #0 \n", "AND R1, R1, #0 \n", "ADD R1, R1, #9 ;R1 = counter \n", " \n", "SCANF_MULLOOP \n", "ADD R2, R2, R0 \n", "ADD R1, R1, #-1 \n", "BRnp SCANF_MULLOOP \n", " \n", "ADD R7, R7, #1 \n", "BRnzp SCANF_CALC \n", " \n", "SCANF_CALCDONE\t\t\t \n", "\n", "LD R0, SCANF_MINUS\n", "LD R1, SCANF_BUF\n", "ADD R0, R0, R1\n", "BRnp SCANF_NOTNEG\n", "NOT R2, R2\n", "ADD R2, R2, #1\n", "\n", "SCANF_NOTNEG\n", " \n", " \n", "ADD R5, R5, #1 \n", "LDR R0, R5, #0 \t\t\n", " \n", "STR R2, R0, #0\t ;store decimal number into address \n", " \n", ";ADD R6, R6, #7 \n", " \n", "LDR R4, R6, #0 \n", "ADD R6, R6, #1\t\t;restoring current ptr into format string \n", " \n", " \n", "ADD R4, R4, #1\t ;point to next element of format string \n", "BRnzp SCANF_LOOP\n", " \n", " \n", "SCANF_STR \n", "LD R1, SCANF_S\n", "ADD R0, R2, #0 \n", "ADD R0, R0, R1 \n", "BRnp SCANF_ERROR\n", " \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%s found\n", "ADD R6, R6, #-1\t\t;saving current ptr into format string \n", "STR R4, R6, #0 \n", " \n", "ADD R5, R5, #1\t\t;getting starting addr of space for string to be read in \n", "LDR R4, R5, #0 \n", " \n", "SCANSTRLOOP \n", "GETC \n", "OUT\n", "STR R0, R4, #0\t\t;Reading and storing typed char \n", "ADD R4, R4, #1 \n", " \n", "ADD R0, R0, #-10\t;End of string? Looking for CR (0x000A) \n", "BRnp SCANSTRLOOP \n", " \n", "SCANSTRDONE \n", "AND R0, R0, #0\t\t;null terminate string \n", "STR R0, R4, #-1 \n", " \n", "LDR R4, R6, #0\t\t;restore r4 \n", "ADD R6, R6, #1 \n", " \n", "ADD R4, R4, #1 \n", "BRnzp SCANF_LOOP\n", " \n", " \n", "SCANF_MATCHCHAR \n", "ADD R4, R4, #1\n", "GETC \n", "OUT\n", "NOT R0, R0\n", "ADD R0, R0, #1\n", "ADD R0, R0, R2 \n", "BRz SCANF_LOOP\n", " \n", "SCANF_ERROR\n", "SCANF_DONE\n", " \n", "LDR R4, R6, #0\t\t;restore R4 \n", "ADD R6, R6, #1 \n", " \n", "LDR R5, R6, #0\t\t;restore bp \n", "ADD R6, R6, #1 \n", " \n", "LDR R7, R6, #0\t\t;restore ret addr \n", "ADD R6, R6, #1 \n", " \n", "RET \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", ";\tvoid printf(const char *format, ...)\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", "\n", "PRINTF_PERCENT .FILL -37\n", "PRINTF_C .FILL -99\n", "PRINTF_D .FILL -100\n", "PRINTF_S .FILL -115\n", "PRINTF_B .FILL -98\n", "PRINTF_O .FILL -111\n", "PRINTF_X .FILL -120\n", "PRINTF_ASCII .FILL 48 \t\t;postive ascii value of '0'\n", ".FILL 49\n", ".FILL 50\n", ".FILL 51\n", ".FILL 52\n", ".FILL 53\n", ".FILL 54\n", ".FILL 55\n", ".FILL 56\n", ".FILL 57\n", ".FILL 65 ;A\n", ".FILL 66\n", ".FILL 67\n", ".FILL 68\n", ".FILL 69\n", ".FILL 70\n", "PRINTF_MINUS .FILL 45 \n", "PRINTF_BUF .BLKW 18\n", " \n", "\n", "lc3_printf\n", "ADD R6, R6, #-2\n", "STR R7, R6, #0\t\t;return address\n", "ADD R6, R6, #-1\n", "STR R5, R6, #0\n", "ADD R5, R6, #-1\n", "\n", "ADD R6, R6, #-1\n", "STR R4, R6, #0\n", "\n", "ADD R5, R5, #4\t\t;cheating with the bp (no longer bp)\n", "LDR R4, R5, #0\t\t;got addr of format string\n", "\n", "\n", "PRINTF_LOOP\t;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", "\n", "LDR R0, R4, #0\n", "\n", "ADD R0, R0, #0\t\t;End of string? (0x0000)\n", "BRz PRINTF_DONE\n", "\n", "ADD R2, R0, #0\n", "LD R1, PRINTF_PERCENT\n", "ADD R2, R2, R1\n", "BRnp PRINTF_CHAR\t\t\n", "\n", "ADD R4, R4, #1\n", "LDR R0, R4, #0\n", ";is it %c?\n", "ADD R2, R0, #0\n", "LD R3, PRINTF_C\n", "ADD R2, R2, R3\n", "BRnp PRINTF_CHECKSTR\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%c\n", "ADD R5, R5, #1\n", "LDR R0, R5, #0\n", "\n", "PRINTF_CHAR\n", "OUT\n", "\n", "ADD R4, R4, #1\n", "BRnzp PRINTF_LOOP\n", "\n", "PRINTF_CHECKSTR\n", ";is it %s?\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_S\n", "ADD R2, R2, R7\n", "BRnp PRINTF_CHECKDEC\t\t\n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%s\n", "\n", "ADD R5, R5, #1\n", "LDR R0, R5, #0\n", "PUTS\n", "\n", "ADD R4, R4, #1\n", "BRnzp PRINTF_LOOP\n", "\n", "PRINTF_CHECKDEC\n", ";is it %d?\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_D\n", "ADD R2, R2, R7\n", ";BRnp PRINTF_ERROR\n", "BRnp PRINTF_CHECKHEX\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-10\t\t;going to divide by 10 by using sub loop\n", "BRnzp PRINTF_NUM\n", "\n", "PRINTF_CHECKHEX\n", "\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_X\n", "ADD R2, R2, R7\n", "BRnp PRINTF_CHECKOCT\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-16\t\t;going to divide by 10 by using sub loop\n", "BRnzp PRINTF_NUM\n", "\n", "PRINTF_CHECKOCT\n", "\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_O\n", "ADD R2, R2, R7\n", "BRnp PRINTF_CHECKBIN\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-8\t\t;going to divide by 10 by using sub loop\n", "BRnzp PRINTF_NUM\n", "\n", "PRINTF_CHECKBIN\n", "\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_B\n", "ADD R2, R2, R7\n", "BRnp PRINTF_ERROR\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-2\t\t;going to divide by 10 by using sub loop\n", ";BRnzp PRINTF_NUM\n", "\n", "\n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%d\n", "PRINTF_NUM\n", "\n", "LEA R7, PRINTF_BUF\n", "ADD R7, R7, #15 \n", "ADD R7, R7, #1 \n", "\n", ";AND R2, R2, #0\n", ";ADD R2, R2, #-10\t\t;going to divide by 10 by using sub loop\n", "\n", "ADD R5, R5, #1\t\t\t;acquire the binary number\n", "LDR R0, R5, #0\n", "\n", "ADD R0, R0, #0\n", "BRzp PRINTF_DECPOS \n", "\n", "NOT R0, R0\t\t\t\t;make num positive for sub loop\n", "ADD R0, R0, #1\n", "\n", "PRINTF_DECPOS\n", "\n", "AND R3, R3, #0\n", "ADD R3, R3, #-1\n", "\n", "PRINTF_DIVLOOP\n", "ADD R3, R3, #1\t\t\t;num/10 \n", "ADD R0, R0, R2\t\t\t;R0 = num % 10 - 10\n", "BRzp PRINTF_DIVLOOP\n", "\n", "ADD R3, R3, #0\n", "BRz PRINTF_LASTDIGIT\n", "\n", ";LD R1, PRINTF_ASCII\n", ";ADD R1, R1, R0\n", ";NOT R2, R2\n", ";ADD R1, R1, R2 \n", ";ADD R1, R1, #1\n", ";NOT R2, R2\n", ";;;;;ADD R1, R1, #10\n", ";STR R1, R7, #0\n", ";ADD R7, R7, #-1\t\t\t;stored ascii value of one digit\n", "\n", "LEA R1, PRINTF_ASCII\n", "ADD R1, R1, R0\n", "NOT R2, R2\n", "ADD R1, R1, R2 \n", "ADD R1, R1, #1\n", "NOT R2, R2\n", "LDR R1, R1, #0\n", "STR R1, R7, #0\n", "ADD R7, R7, #-1\t\t\t;stored ascii value of one digit\n", "\n", "ADD R0, R3, #0\t\t\t;num/10\n", "\n", "BRnzp PRINTF_DECPOS\n", "\n", "PRINTF_LASTDIGIT\n", "\n", ";LD R1, PRINTF_ASCII\n", ";ADD R1, R1, R0\n", ";ADD R1, R1, #10\n", ";STR R1, R7, #0\n", "\n", "LEA R1, PRINTF_ASCII\n", "ADD R1, R1, R0\n", "NOT R2, R2\n", "ADD R1, R1, R2 \n", "ADD R1, R1, #1\n", "NOT R2, R2\n", "LDR R1, R1, #0\n", "STR R1, R7, #0\t\t\t;stored ascii value of highest order digit\n", "\n", "LDR R0, R5, #0\n", "ADD R0, R0, #0\n", "BRzp PRINTF_DECSTRING\n", "\n", "LD R0, PRINTF_MINUS\t\t;num was negative\n", "ADD R7, R7, #-1\n", "STR R0, R7, #0\t\t\t;stored ascii value negative sign\n", "\n", "PRINTF_DECSTRING\t\t;print the calculated string\n", "ADD R0, R7, #0\n", "PUTS\n", "\n", "ADD R4, R4, #1\n", "BRnzp PRINTF_LOOP\n", "\n", "PRINTF_ERROR\n", "PRINTF_DONE\n", "\n", "LDR R4, R6, #0\t\t;restore R4\n", "ADD R6, R6, #1\n", "\n", "LDR R5, R6, #0\t\t;restore bp\n", "ADD R6, R6, #1\n", "\n", "LDR R7, R6, #0\t\t;restore ret addr\n", "ADD R6, R6, #1\n", "\n", "RET\n", "\n", "GLOBAL_DATA_START\n", "L1_Testme .FILL lc3_L1_Testme\n", "scanf .FILL lc3_scanf\n", "printf .FILL lc3_printf\n", "L4_Testme .STRINGZ \"Result = %d\\n\"\n", "L3_Testme .FILL #3\n", "L2_Testme .FILL #5\n", ".END\n" ] }, { "cell_type": "code", "execution_count": 206, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Result = 28\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 367\n", "Cycles: 2721 (0.001360 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 1 Z: 0 P: 0 \n", "R0: x0000 R1: xFFDB R2: xFFE5 R3: x0000 \n", "R4: x3181 R5: xEFFF R6: xEFFE R7: x300C \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "code", "execution_count": 232, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created file '/home/dblank/public_html/CS240 Computer Organization/2015-Fall/Notes/Optimize.c'.\n" ] } ], "source": [ "%%file Optimize.c\n", "#include \n", "\n", "int main() {\n", " printf(\"The answer is %d\\n\", 88/3);\n", " return 0;\n", "}" ] }, { "cell_type": "code", "execution_count": 233, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cpp: Optimize.c:6 No newline at end of file\r\n", "STARTING PASS 1\r\n", "0 errors found in first pass.\r\n", "STARTING PASS 2\r\n", "0 errors found in second pass.\r\n", "\n" ] } ], "source": [ "!lcc -o Optimize.obj Optimize.c" ] }, { "cell_type": "code", "execution_count": 234, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Warning: Possible overflow of immediate: -16 at line 419\n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Assembled! Use %dis or %dump to examine; use %exe to run.\n" ] } ], "source": [ "%include Optimize.asm" ] }, { "cell_type": "code", "execution_count": 235, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The answer is 29\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 405\n", "Cycles: 3059 (0.001530 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 1 Z: 0 P: 0 \n", "R0: x0000 R1: xFFDB R2: xFFE5 R3: x0000 \n", "R4: x315F R5: xEFFF R6: xEFFE R7: x300C \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%load Optimize.asm" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ ".Orig x3000\n", "INIT_CODE\n", "LEA R6, #-1\n", "ADD R5, R6, #0\n", "ADD R6, R6, R6\n", "ADD R6, R6, R6\n", "ADD R6, R6, R5\n", "ADD R6, R6, #-1\n", "ADD R5, R5, R5\n", "ADD R5, R6, #0\n", "LD R4, GLOBAL_DATA_POINTER\n", "LD R7, GLOBAL_MAIN_POINTER\n", "jsrr R7\n", "HALT\n", "\n", "GLOBAL_DATA_POINTER .FILL GLOBAL_DATA_START\n", "GLOBAL_MAIN_POINTER .FILL main\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;main;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", "main\n", "ADD R6, R6, #-2\n", "STR R7, R6, #0\n", "ADD R6, R6, #-1\n", "STR R5, R6, #0\n", "ADD R5, R6, #-1\n", "\n", "ADD R6, R6, #-1\n", "ADD R7, R4, #4\n", "ldr R7, R7, #0\n", "ADD R6, R6, #-1\n", "STR R7, R6, #0\n", "ADD R7, R4, #5\n", "ADD R6, R6, #-1\n", "STR R7, R6, #0\n", "ADD R0, R4, #2\n", "LDR R0, R0, #0\n", "jsrr R0\n", "ADD R7, R4, #3\n", "ldr R7, R7, #0\n", "lc3_L1_Optimize\n", "STR R7, R5, #3\n", "ADD R6, R5, #1\n", "LDR R5, R6, #0\n", "ADD R6, R6, #1\n", "LDR R7, R6, #0\n", "ADD R6, R6, #1\n", "RET\n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \n", ";\tvoid scanf(const char *format, ...) \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \n", "\n", "SCANF_PERCENT .FILL -37\n", "SCANF_C .FILL -99\n", "SCANF_D .FILL -100\n", "SCANF_S .FILL -115 \n", "SCANF_0 .FILL -48 \n", "SCANF_9 .FILL -57 \n", "SCANF_MINUS .FILL -45 \n", "SCANF_BUF .BLKW 6\n", " \n", "lc3_scanf \n", "ADD R6, R6, #-2 \n", "STR R7, R6, #0 \n", " \n", "ADD R6, R6, #-1\t\t;save R5 = bp \n", "STR R5, R6, #0\t\t \n", "ADD R5, R6, #-1 \n", " \n", "ADD R6, R6, #-1\t\t;save R4 = gp \n", "STR R4, R6, #0 \n", " \n", "ADD R5, R5, #4\t\t;cheating with the bp (no longer bp) \n", "LDR R4, R5, #0\t\t;got addr of format string \n", " \n", "\n", " \n", "\n", "SCANF_LOOP\t;outer loop, R0=tmp register for use with GETC \n", "\t\t\t;R2 holds either cur letter of format string or \n", "\t\t\t;current addr to store a char, dec, or string \n", " \n", " \n", " \n", "LDR R2, R4, #0 \n", " \n", "ADD R2, R2, #0\t\t;End of format string? (0x0000) \n", "BRz SCANF_DONE\n", " \n", "LD R1, SCANF_PERCENT\n", "ADD R0, R2, #0 \n", "ADD R0, R0, R1\t\t\n", "BRnp SCANF_MATCHCHAR\t\t ;% not found\n", " \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;% found! \n", "ADD R4, R4, #1\t\t;R4 points to next char of format string \n", "LDR R2, R4, #0 \n", " \n", "LD R1, SCANF_C\n", "ADD R0, R2, #0\t\t;next char = c? \n", "ADD R0, R0, R1 \n", "BRnp SCANF_CHECKD \n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%c found\n", "ADD R5, R5, #1 \n", "LDR R2, R5, #0\t\t;R2 has addr for char to be read into \n", "\n", "GETC \n", "OUT\n", "STR R0, R2, #0 \n", " \n", "ADD R4, R4, #1 \n", "BRnzp SCANF_LOOP\n", " \n", "SCANF_CHECKD \n", ";is it %d? \n", "LD R1, SCANF_D\n", "ADD R0, R2, #0 \n", "ADD R0, R0, R1 \n", "BRnp SCANF_STR \n", " \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%d found\n", ";consider using vars to store reg\n", ";registers 0,1,2,3,7 available as tmp regs\n", " \n", " \n", "ADD R6, R6, #-1\t\t;saving current ptr into format string \n", "STR R4, R6, #0 \n", " \n", ";ADD R6, R6, #-7\t\t ;making 7byte buffer for ascbin \n", ";ADD R4, R6, #0\t\t ;ptr into that buffer \n", "LEA R4, SCANF_BUF \n", "LD R2, SCANF_0\n", "LD R1, SCANF_9\n", " \n", "SCANF_SCANNUM \n", " \n", "GETC \n", "OUT\n", "STR R0, R4, #0\t\t;Reading and storing typed char \n", " \n", "ADD R0, R2, R0 \n", "BRZP SCANF_CHECKEDLOWER \n", "\n", "LDR R0, R4, #0 \n", "LD R7, SCANF_MINUS\n", "ADD R0, R0, R7\n", "BRz SCANF_CHECKEDLOWER\n", " \n", "LEA R0, SCANF_BUF \n", "NOT R0, R0 \n", "ADD R0, R0, #1 \n", "ADD R0, R4, R0 \n", "BRz SCANF_SCANNUM\t ;buffer is empty and wrong char, go to error?\n", " \n", "ADD R4, R4, #-1 \t\t;fixme: need to save this char\n", "BRnzp SCANF_NUMDONE \n", " \n", " \n", "SCANF_CHECKEDLOWER \n", " \n", "LDR R0, R4, #0 \n", "ADD R0, R1, R0 \n", "BRNZ SCANF_CHECKEDUPPER \n", " \n", "LEA R0, SCANF_BUF \n", "NOT R0, R0 \n", "ADD R0, R0, #1 \n", "ADD R0, R4, R0 \n", "BRz SCANF_SCANNUM\t ;buffer is empty and wrong char, go to error?\n", " \n", "ADD R4, R4, #-1 \t\t;fixme: need to save this char\n", "BRnzp SCANF_NUMDONE \n", " \n", "SCANF_CHECKEDUPPER \n", " \n", "LEA R0, SCANF_BUF \n", "ADD R0, R0, #5 \n", "\n", "NOT R0, R0 \n", "ADD R0, R0, #1 \n", "ADD R0, R4, R0 \n", "BRz SCANF_NUMDONE\t ;buffer is full \n", " \n", "ADD R4, R4, #1 \n", "BRnzp SCANF_SCANNUM \n", " \n", "SCANF_NUMDONE \n", "\t\t ;R4 points to last char entered in (ones digit) \n", " \n", ";ADD R7, R6, #0\t ;R7 points to the highest order digit \n", "LEA R7, SCANF_BUF \n", "LD R0, SCANF_MINUS\n", "LD R1, SCANF_BUF\n", "ADD R0, R0, R1\n", "BRnp SCANF_NOTMINUS\n", "ADD R7, R7, #1 \t;fixme check for - -\n", "\n", "SCANF_NOTMINUS\n", " \n", ";STR R2, R6, #-1 ;psuedo stored -'0' on stack \n", "AND R2, R2, #0\t ;R2 acts as the acumulator \n", " \n", "SCANF_CALC \n", " \n", "LDR R0, R7, #0 \n", ";LDR R1, R6, #-1 \n", "LD R1, SCANF_0\n", "ADD R0, R0, R1 \n", "ADD R2, R2, R0 \n", " \n", "NOT R1, R7 \n", "ADD R1, R1, #1 \n", "ADD R1, R4, R1 \n", "BRz SCANF_CALCDONE \n", "\t\t\t ;R2 = 10*R2 \n", "ADD R0, R2, #0 \n", "AND R1, R1, #0 \n", "ADD R1, R1, #9 ;R1 = counter \n", " \n", "SCANF_MULLOOP \n", "ADD R2, R2, R0 \n", "ADD R1, R1, #-1 \n", "BRnp SCANF_MULLOOP \n", " \n", "ADD R7, R7, #1 \n", "BRnzp SCANF_CALC \n", " \n", "SCANF_CALCDONE\t\t\t \n", "\n", "LD R0, SCANF_MINUS\n", "LD R1, SCANF_BUF\n", "ADD R0, R0, R1\n", "BRnp SCANF_NOTNEG\n", "NOT R2, R2\n", "ADD R2, R2, #1\n", "\n", "SCANF_NOTNEG\n", " \n", " \n", "ADD R5, R5, #1 \n", "LDR R0, R5, #0 \t\t\n", " \n", "STR R2, R0, #0\t ;store decimal number into address \n", " \n", ";ADD R6, R6, #7 \n", " \n", "LDR R4, R6, #0 \n", "ADD R6, R6, #1\t\t;restoring current ptr into format string \n", " \n", " \n", "ADD R4, R4, #1\t ;point to next element of format string \n", "BRnzp SCANF_LOOP\n", " \n", " \n", "SCANF_STR \n", "LD R1, SCANF_S\n", "ADD R0, R2, #0 \n", "ADD R0, R0, R1 \n", "BRnp SCANF_ERROR\n", " \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%s found\n", "ADD R6, R6, #-1\t\t;saving current ptr into format string \n", "STR R4, R6, #0 \n", " \n", "ADD R5, R5, #1\t\t;getting starting addr of space for string to be read in \n", "LDR R4, R5, #0 \n", " \n", "SCANSTRLOOP \n", "GETC \n", "OUT\n", "STR R0, R4, #0\t\t;Reading and storing typed char \n", "ADD R4, R4, #1 \n", " \n", "ADD R0, R0, #-10\t;End of string? Looking for CR (0x000A) \n", "BRnp SCANSTRLOOP \n", " \n", "SCANSTRDONE \n", "AND R0, R0, #0\t\t;null terminate string \n", "STR R0, R4, #-1 \n", " \n", "LDR R4, R6, #0\t\t;restore r4 \n", "ADD R6, R6, #1 \n", " \n", "ADD R4, R4, #1 \n", "BRnzp SCANF_LOOP\n", " \n", " \n", "SCANF_MATCHCHAR \n", "ADD R4, R4, #1\n", "GETC \n", "OUT\n", "NOT R0, R0\n", "ADD R0, R0, #1\n", "ADD R0, R0, R2 \n", "BRz SCANF_LOOP\n", " \n", "SCANF_ERROR\n", "SCANF_DONE\n", " \n", "LDR R4, R6, #0\t\t;restore R4 \n", "ADD R6, R6, #1 \n", " \n", "LDR R5, R6, #0\t\t;restore bp \n", "ADD R6, R6, #1 \n", " \n", "LDR R7, R6, #0\t\t;restore ret addr \n", "ADD R6, R6, #1 \n", " \n", "RET \n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", ";\tvoid printf(const char *format, ...)\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", "\n", "PRINTF_PERCENT .FILL -37\n", "PRINTF_C .FILL -99\n", "PRINTF_D .FILL -100\n", "PRINTF_S .FILL -115\n", "PRINTF_B .FILL -98\n", "PRINTF_O .FILL -111\n", "PRINTF_X .FILL -120\n", "PRINTF_ASCII .FILL 48 \t\t;postive ascii value of '0'\n", ".FILL 49\n", ".FILL 50\n", ".FILL 51\n", ".FILL 52\n", ".FILL 53\n", ".FILL 54\n", ".FILL 55\n", ".FILL 56\n", ".FILL 57\n", ".FILL 65 ;A\n", ".FILL 66\n", ".FILL 67\n", ".FILL 68\n", ".FILL 69\n", ".FILL 70\n", "PRINTF_MINUS .FILL 45 \n", "PRINTF_BUF .BLKW 18\n", " \n", "\n", "lc3_printf\n", "ADD R6, R6, #-2\n", "STR R7, R6, #0\t\t;return address\n", "ADD R6, R6, #-1\n", "STR R5, R6, #0\n", "ADD R5, R6, #-1\n", "\n", "ADD R6, R6, #-1\n", "STR R4, R6, #0\n", "\n", "ADD R5, R5, #4\t\t;cheating with the bp (no longer bp)\n", "LDR R4, R5, #0\t\t;got addr of format string\n", "\n", "\n", "PRINTF_LOOP\t;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n", "\n", "LDR R0, R4, #0\n", "\n", "ADD R0, R0, #0\t\t;End of string? (0x0000)\n", "BRz PRINTF_DONE\n", "\n", "ADD R2, R0, #0\n", "LD R1, PRINTF_PERCENT\n", "ADD R2, R2, R1\n", "BRnp PRINTF_CHAR\t\t\n", "\n", "ADD R4, R4, #1\n", "LDR R0, R4, #0\n", ";is it %c?\n", "ADD R2, R0, #0\n", "LD R3, PRINTF_C\n", "ADD R2, R2, R3\n", "BRnp PRINTF_CHECKSTR\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%c\n", "ADD R5, R5, #1\n", "LDR R0, R5, #0\n", "\n", "PRINTF_CHAR\n", "OUT\n", "\n", "ADD R4, R4, #1\n", "BRnzp PRINTF_LOOP\n", "\n", "PRINTF_CHECKSTR\n", ";is it %s?\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_S\n", "ADD R2, R2, R7\n", "BRnp PRINTF_CHECKDEC\t\t\n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%s\n", "\n", "ADD R5, R5, #1\n", "LDR R0, R5, #0\n", "PUTS\n", "\n", "ADD R4, R4, #1\n", "BRnzp PRINTF_LOOP\n", "\n", "PRINTF_CHECKDEC\n", ";is it %d?\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_D\n", "ADD R2, R2, R7\n", ";BRnp PRINTF_ERROR\n", "BRnp PRINTF_CHECKHEX\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-10\t\t;going to divide by 10 by using sub loop\n", "BRnzp PRINTF_NUM\n", "\n", "PRINTF_CHECKHEX\n", "\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_X\n", "ADD R2, R2, R7\n", "BRnp PRINTF_CHECKOCT\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-16\t\t;going to divide by 10 by using sub loop\n", "BRnzp PRINTF_NUM\n", "\n", "PRINTF_CHECKOCT\n", "\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_O\n", "ADD R2, R2, R7\n", "BRnp PRINTF_CHECKBIN\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-8\t\t;going to divide by 10 by using sub loop\n", "BRnzp PRINTF_NUM\n", "\n", "PRINTF_CHECKBIN\n", "\n", "ADD R2, R0, #0\n", "LD R7, PRINTF_B\n", "ADD R2, R2, R7\n", "BRnp PRINTF_ERROR\n", "\n", "AND R2, R2, #0\n", "ADD R2, R2, #-2\t\t;going to divide by 10 by using sub loop\n", ";BRnzp PRINTF_NUM\n", "\n", "\n", "\n", ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%d\n", "PRINTF_NUM\n", "\n", "LEA R7, PRINTF_BUF\n", "ADD R7, R7, #15 \n", "ADD R7, R7, #1 \n", "\n", ";AND R2, R2, #0\n", ";ADD R2, R2, #-10\t\t;going to divide by 10 by using sub loop\n", "\n", "ADD R5, R5, #1\t\t\t;acquire the binary number\n", "LDR R0, R5, #0\n", "\n", "ADD R0, R0, #0\n", "BRzp PRINTF_DECPOS \n", "\n", "NOT R0, R0\t\t\t\t;make num positive for sub loop\n", "ADD R0, R0, #1\n", "\n", "PRINTF_DECPOS\n", "\n", "AND R3, R3, #0\n", "ADD R3, R3, #-1\n", "\n", "PRINTF_DIVLOOP\n", "ADD R3, R3, #1\t\t\t;num/10 \n", "ADD R0, R0, R2\t\t\t;R0 = num % 10 - 10\n", "BRzp PRINTF_DIVLOOP\n", "\n", "ADD R3, R3, #0\n", "BRz PRINTF_LASTDIGIT\n", "\n", ";LD R1, PRINTF_ASCII\n", ";ADD R1, R1, R0\n", ";NOT R2, R2\n", ";ADD R1, R1, R2 \n", ";ADD R1, R1, #1\n", ";NOT R2, R2\n", ";;;;;ADD R1, R1, #10\n", ";STR R1, R7, #0\n", ";ADD R7, R7, #-1\t\t\t;stored ascii value of one digit\n", "\n", "LEA R1, PRINTF_ASCII\n", "ADD R1, R1, R0\n", "NOT R2, R2\n", "ADD R1, R1, R2 \n", "ADD R1, R1, #1\n", "NOT R2, R2\n", "LDR R1, R1, #0\n", "STR R1, R7, #0\n", "ADD R7, R7, #-1\t\t\t;stored ascii value of one digit\n", "\n", "ADD R0, R3, #0\t\t\t;num/10\n", "\n", "BRnzp PRINTF_DECPOS\n", "\n", "PRINTF_LASTDIGIT\n", "\n", ";LD R1, PRINTF_ASCII\n", ";ADD R1, R1, R0\n", ";ADD R1, R1, #10\n", ";STR R1, R7, #0\n", "\n", "LEA R1, PRINTF_ASCII\n", "ADD R1, R1, R0\n", "NOT R2, R2\n", "ADD R1, R1, R2 \n", "ADD R1, R1, #1\n", "NOT R2, R2\n", "LDR R1, R1, #0\n", "STR R1, R7, #0\t\t\t;stored ascii value of highest order digit\n", "\n", "LDR R0, R5, #0\n", "ADD R0, R0, #0\n", "BRzp PRINTF_DECSTRING\n", "\n", "LD R0, PRINTF_MINUS\t\t;num was negative\n", "ADD R7, R7, #-1\n", "STR R0, R7, #0\t\t\t;stored ascii value negative sign\n", "\n", "PRINTF_DECSTRING\t\t;print the calculated string\n", "ADD R0, R7, #0\n", "PUTS\n", "\n", "ADD R4, R4, #1\n", "BRnzp PRINTF_LOOP\n", "\n", "PRINTF_ERROR\n", "PRINTF_DONE\n", "\n", "LDR R4, R6, #0\t\t;restore R4\n", "ADD R6, R6, #1\n", "\n", "LDR R5, R6, #0\t\t;restore bp\n", "ADD R6, R6, #1\n", "\n", "LDR R7, R6, #0\t\t;restore ret addr\n", "ADD R6, R6, #1\n", "\n", "RET\n", "\n", "GLOBAL_DATA_START\n", "L1_Optimize .FILL lc3_L1_Optimize\n", "scanf .FILL lc3_scanf\n", "printf .FILL lc3_printf\n", "L4_Optimize .FILL #0\n", "L3_Optimize .FILL #29\n", "L2_Optimize .STRINGZ \"The answer is %d\\n\"\n", ".END\n" ] }, { "cell_type": "code", "execution_count": 229, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Welcome to the LC-3 simulator.\n", "\n", "The contents of the LC-3 tools distribution, including sources, management\n", "tools, and data, are Copyright (c) 2003 Steven S. Lumetta.\n", "\n", "The LC-3 tools distribution is free software covered by the GNU General\n", "Public License, and you are welcome to modify it and/or distribute copies\n", "of it under certain conditions. The file COPYING (distributed with the\n", "tools) specifies those conditions. There is absolutely no warranty for\n", "the LC-3 tools distribution, as described in the file NO_WARRANTY (also\n", "distributed with the tools).\n", "\n", "Have fun.\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3000\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ "%reset" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Calysto LC3", "language": "gas", "name": "calysto_lc3" }, "language_info": { "codemirror_mode": { "name": "gas", "version": 3 }, "file_extension": ".asm", "mimetype": "text/x-gas", "name": "gas" } }, "nbformat": 4, "nbformat_minor": 0 }